package com.xing.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xing.common.dto.BrowseDto;
import com.xing.model.Collect;
import com.xing.mapper.CollectMapper;
import com.xing.service.CollectService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xing.util.BrowseKeyUtils;
import com.xing.util.KeyUtils;
import com.xing.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 柠檬有点甜
 * @since 2021-10-11
 */
@Service
public class CollectServiceImpl extends ServiceImpl<CollectMapper, Collect> implements CollectService {

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    CollectMapper collectMapper;

    @Override
    public boolean userCollectState(String blogId, String userId) {

        String key = KeyUtils.MAP_KEY_COLLECT;
        String item= KeyUtils.getKey(userId,blogId);
        //判断该记录值是否存在
        if (ObjectUtil.isNotEmpty(redisUtil.hget(key,item))){
            //判断收藏记录值是否收藏
            if ("1".equals(String.valueOf(redisUtil.hget(key,item)))){
                return true;
            }
        }
        return false;
    }

    @Override
    @Transactional
    public void collectBlog(String blogId, String userId) {
        /*key是收藏的标志，map主要存<userid,blogid>*/
        String key = KeyUtils.MAP_KEY_COLLECT;
        String item= KeyUtils.getKey(userId,blogId);

        /*如果为true说明不存在item说明第一次来*/
        if (!redisUtil.opsForValue(key,item)){
            /*给数据库设置收藏记录值*/
            Collect collect = new Collect();
            collect.setUserId(Integer.valueOf(userId)).setBlogId(Integer.valueOf(blogId)).setStatus(1);
            collectMapper.insert(collect);
        }else
            {
            /*不是第一次来只需要修改点赞状态就行了*/
            /*查询该收藏记录*/
            Collect collect = collectMapper.selectOne(new QueryWrapper<Collect>().eq("blog_id", blogId).eq("user_id", userId));
            collect.setStatus(1);
            System.out.println(collect);
            collectMapper.updateById(collect);
        }
        // 给redis设置记录值
        redisUtil.hset(key,item,1);
        //给redis文章增加收藏记录
        redisUtil.hincr(KeyUtils.MAP_KEY_COLLECT_COUNT,blogId,1);
    }


    @Override
    @Transactional
    public void unCollectBlog(String blogId, String userId) {
        String key = KeyUtils.MAP_KEY_COLLECT;
        String item= KeyUtils.getKey(userId,blogId);
        if (redisUtil.opsForValue(key,item)){
            /*查询该收藏记录*/
            Collect collect = collectMapper.selectOne(new QueryWrapper<Collect>().eq("blog_id", blogId).eq("user_id", userId));
            collect.setStatus(0);
            collectMapper.updateById(collect);
            // 给redis删除记录值
            redisUtil.hset(key,item,0);
            //给redis文章增加减少收藏记录
            redisUtil.hincr(KeyUtils.MAP_KEY_COLLECT_COUNT,blogId,-1);

        }


    }

    @Override
    public List<BrowseDto> getCollectCountFromRedis() {
        Cursor<Map.Entry<Object, Object>> cursor  = redisUtil.hscan(KeyUtils.MAP_KEY_COLLECT_COUNT, ScanOptions.NONE);
        ArrayList<BrowseDto> list = new ArrayList<>();
        while (cursor.hasNext()){
            Map.Entry<Object, Object> entry = cursor.next();
            Long key = Long.valueOf((String) entry.getKey());
            BrowseDto browseDto = new BrowseDto();
            browseDto.setKey(key); //文章id
            browseDto.setBrowseCount(Long.valueOf(String.valueOf(entry.getValue())));//储存的浏览量
            //因为用户会同时收藏和取消收藏
            if (browseDto.getBrowseCount()!=0){
                list.add(browseDto);
            }
            //存到List后从Redis中删除
            redisUtil.hdel(KeyUtils.MAP_KEY_COLLECT_COUNT,entry.getKey());
        }
        return list;

    }
}
